package com.zhan.easyexcelorder.service.impl;

import com.zhan.easyexcelorder.model.SysMenu;
import com.zhan.easyexcelorder.model.SysRole;
import com.zhan.easyexcelorder.model.SysUser;
import com.zhan.easyexcelorder.repository.SysMenuRepository;
import com.zhan.easyexcelorder.repository.SysRoleRepository;
import com.zhan.easyexcelorder.service.SysRoleService;
import com.zhan.jpa.service.impl.AbstractServiceImpl;
import com.zhan.utils.page.QueryCondition;
import com.zhan.utils.page.QueryItem;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

@Service
public class SysRoleServiceImpl extends AbstractServiceImpl<SysRoleRepository, SysRole> implements SysRoleService {

    @Autowired
    private SysMenuRepository sysMenuRepository;

    @Override
    protected void createPredicate(Root<SysRole> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder, List<Predicate> list, QueryCondition condition) {
        List<QueryItem> query = condition.getQuery();
        if (Objects.nonNull(query)) {
            query.forEach(q -> {
                String column = q.getColumn();
                Object value = q.getValue();
                if (Objects.nonNull(value)) {
                    if ("name".equals(column)) {
                        String temp = "%" + value.toString() + "%";
                        list.add(criteriaBuilder.like(root.get("name").as(String.class), temp));
                    } else if ("userId".equals(column)) {
                        ListJoin<SysRole, SysUser> join = root.join(root.getModel().getList("sysUsers", SysUser.class), JoinType.LEFT);

                        // 创建子查询
                        Subquery<String> subquery = criteriaQuery.subquery(String.class);
                        Root<SysRole> from = subquery.from(SysRole.class);
                        subquery.select(from.get("id")).where(criteriaBuilder.equal(join.get("id").as(Long.class), Long.parseLong(value.toString())));

                        list.add(criteriaBuilder.not(root.get("id").in(subquery)));
                    }
                }
            });
        }

    }

    /**
     * 新增数据时插入菜单列表
     *
     * @param entity
     */
    @Override
    protected void addEntity(SysRole entity) {
        List<Long> ids = addMenuList(entity);
        // 添加父id
        addMenuParent(entity, ids);
    }

    private void addMenuParent(SysRole entity, List<Long> ids) {
        List<Long> parentIds = sysMenuRepository.findAllParentIds(ids);
        List<SysMenu> sysMenus = entity.getSysMenus();
        parentIds.forEach(id -> {
            SysMenu sysMenu = new SysMenu();
            sysMenu.setId(id);
            sysMenus.add(sysMenu);
        });
        entity.setSysMenus(sysMenus);
    }

    /**
     * 修改数据时插入菜单列表
     *
     * @param oldEntity
     * @param entity
     */
    @Override
    protected void updateEntity(SysRole oldEntity, SysRole entity) {
        List<Long> ids = addMenuList(entity);
        // 添加父id
        addMenuParent(entity, ids);
    }

    @Override
    protected void beforeDelete(SysRole entity) throws Exception {
        List<SysUser> sysUsers = entity.getSysUsers();
        if (!Objects.isNull(sysUsers) && !sysUsers.isEmpty()) {
            throw new Exception("有使用该角色的用户，无法删除");
        }
    }

    private List<Long> addMenuList(SysRole entity) {
        StringBuffer stringBuffer = new StringBuffer();
        if (Objects.nonNull(entity.getSysMenus())) {
            List<Long> ids = new ArrayList<>(entity.getSysMenus().size());
            entity.getSysMenus().forEach(t -> {
                com.zhan.utils.model.SysMenu sysMenu = sysMenuRepository.findById(t.getId()).get();
                if ("MENU".equalsIgnoreCase(sysMenu.getMenuType())) {
                    stringBuffer.append(sysMenu.getMenuName()).append("，");
                    ids.add(sysMenu.getId());
                }
            });
            int length = stringBuffer.length();
            if (length > 0) {
                entity.setMenuList(stringBuffer.substring(0, length - 1));
            }
            return ids;
        }
        return Collections.EMPTY_LIST;
    }
}
